package com.whu.MenuHub.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whu.MenuHub.dao.UserFlavorDao;
import com.whu.MenuHub.dao.UserDao;
import com.whu.MenuHub.domain.User;
import com.whu.MenuHub.exception.MenuHubException;
import com.whu.MenuHub.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

@Service
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserService {
    @Autowired
    UserDao userDao;
    @Autowired
    UserFlavorDao flavourDao;
    @Autowired
    PasswordEncoder passwordEncoder;

    //根据用户名获取用户信息
    @Cacheable(cacheNames = "user",key = "#name",condition = "#name!=null")
    @Override
    public User getUserByUserName(String name){
        //获取到user对象
        User user=userDao.getUserByUserName(name);
        return user;
    }

    //根据用户id获取用户信息
    @Override
    @Cacheable(cacheNames = "user",key = "#id",condition = "#id!=null")
    public User getUserByUserID(Integer id){
        return userDao.selectById(id);
    }

    //增加一条用户记录
    @Override
    public User insertUser(User user) throws MenuHubException{
        User user1=getUserByUserName(user.getUsername());
        if(user1!=null){
            throw new MenuHubException(MenuHubException.ErrorType.INSERT_ERROR,"账号名已经存在，用户信息增加失败");
        }
        try{
            //先加密后存储
            user.setPassword(passwordEncoder.encode(user.getPassword()));
            userDao.insertUser(user);
            return user;
        }catch (Exception e){
            throw new MenuHubException(MenuHubException.ErrorType.INSERT_ERROR,"添加用户信息失败");
        }
    }

    //修改一条用户信息
    @Transactional(rollbackFor = MenuHubException.class)
    @Override
    @CacheEvict(cacheNames = "user",key = "#user.id")
    public void updateUserByID(User user,Boolean encoder) throws MenuHubException{
        try{
            //对修改的密码进行加密
            if(user.getPassword()!=null&&encoder){
                user.setPassword(passwordEncoder.encode(user.getPassword()));
            }
            //修改信息
            userDao.updateById(user);
        }catch (Exception e){
            throw new MenuHubException(MenuHubException.ErrorType.UPDATE_ERROR,"修改用户信息失败");
        }
    }

    //删除一条用户信息，考虑外键约束
    @Transactional(rollbackFor = MenuHubException.class)
    @Override
    @CacheEvict(cacheNames = "user",key = "#id")
    public void deleteUserByID(Integer id) throws MenuHubException{
        try{
            if(flavourDao.selectById(id)!=null){
                //先删除口味偏好表中的信息
                flavourDao.deleteById(id);
            }
            userDao.deleteById(id);
        }catch (Exception e){
            throw new MenuHubException(MenuHubException.ErrorType.DELETE_ERROR,"删除用户信息失败");
        }
    }

    //分页获取用户信息
    @Override
    public IPage<User> findUsers(Map<String, Object> condition, Integer pageNum, Integer pageSize) {
        IPage page = new Page(pageNum, pageSize);
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.like(condition.containsKey("username"), "username", condition.get("name"));
        qw.eq(condition.containsKey("role"), "role", condition.get("role"));
        qw.eq(condition.containsKey("level"), "level", condition.get("level"));
        return userDao.findUsers(page, qw);
    }
    @Override
    public List<User> getAllUser(){
        //获取全部用户信息
        QueryWrapper<User> qw = new QueryWrapper<>();
        return userDao.selectList(qw);
    }

    @Override
    public List<User> getRecentActiveUser() {
        return userDao.getRecentActiveUser();
    }

    @Override
    public List<User> getHistoryActiveUser() {
        return userDao.getHistoryActiveUser();
    }
    @Override
    @CacheEvict(cacheNames = "rank",key = "#userID")
    public int getRankNum(Integer userID){
        return userDao.getRankNum(userID);
    }
}
